package cn.apthink.calendar;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import cn.apthink.utility.Util;

public class DepartmentCalendarHelper {
	private final Set<DepartmentCalendar> departmentCalendars = new HashSet<DepartmentCalendar>();
	private LocalDate startDate;
	private LocalDate endDate;
	private DepartmentHelper departmentHelper = new DepartmentHelper();
	private HolidayHelper holidayHelper = new HolidayHelper();
	private DepartmentWorkerHelper departmentWorkerHelper = new DepartmentWorkerHelper();
	private WeekHelper weekHelper = new WeekHelper();
	private SpecialWorkDayHelper specialWorkDayHelper = new SpecialWorkDayHelper();
	private WorkCalendarHelper workCalendarHelper = new WorkCalendarHelper();

	public DepartmentCalendarHelper(List<Department> lstDepartment, List<DepartmentWorker> lstDepartmentWorker,
			List<WeekTemplateDetail> lstWeekTemplateDetail, List<WorkCalendar> lstWorkCalendar,
			List<Holiday> lstHoliday, List<SpecialWorkDay> lstDepartmentWorkDayDetail) {
		weekHelper.refreshWeek(lstWeekTemplateDetail);
		departmentHelper.setLstDepartment(lstDepartment);

		departmentWorkerHelper.setDepartmentHelper(departmentHelper);
		departmentWorkerHelper.setLstDepartmentWorker(lstDepartmentWorker);

		holidayHelper.setDepartmentHelper(departmentHelper);
		holidayHelper.setLstHoliday(lstHoliday);

		workCalendarHelper.setDepartmentHelper(departmentHelper);
		workCalendarHelper.setLstWorkcalendar(lstWorkCalendar);

		specialWorkDayHelper.refreshData(lstDepartmentWorkDayDetail);
	}

	public void setRange(LocalDate sd, LocalDate ed) {
		if ((!Util.isEmpty(startDate) && startDate.isAfter(sd)) || (!Util.isEmpty(endDate) && endDate.isBefore(ed)))
			departmentCalendars.clear();
		startDate = sd;
		endDate = ed;
	}

	/**
	 * 获取指定单位工作日历
	 * 
	 * @param id
	 * @return
	 */
	public DepartmentCalendar getDepartmentCalendar(String id) {
		Optional<DepartmentCalendar> o = departmentCalendars.stream().filter(x -> {
			return x.getId().equals(id);
		}).findFirst();
		if (o.isPresent()) {
			return o.get();
		} else {
			DepartmentCalendar dc = _refreshDepartmentCalendar(id);
			departmentCalendars.add(dc);
			return dc;
		}
	}

	private DepartmentCalendar _refreshDepartmentCalendar(String id) {
		DepartmentCalendar dc = new DepartmentCalendar(id);
		List<WorkDay> lstWorkDay = new ArrayList<WorkDay>();
		List<Holiday> lstHoliday = holidayHelper.getHoliday(id);
		List<WorkCalendar> lstWorkCalendar = workCalendarHelper.getWorkCalendar(id);
		WorkCalendar workCalendar = WorkCalendarHelper.getWorkCalendar(lstWorkCalendar, endDate);
		Week week = weekHelper.getWeek(workCalendar.getWeekTemplateId());
		for (LocalDate current = endDate; !current.isBefore(startDate); current = current.minusDays(1)) {
			int worker = departmentWorkerHelper.getDepartmentWorker(id, current);
			// 设置有单位特殊日期模板
			WorkDay workDay = specialWorkDayHelper.getWorkDay(id, current);
			if (!Util.isEmpty(workDay)) {
				workDay.setWorker(worker);
				lstWorkDay.add(workDay);
				continue;
			} else {
				workDay = new WorkDay();
				workDay.setWorker(worker);
				workDay.setCurrent(current);
				lstWorkDay.add(workDay);
			}
			// 设置假期（没有上班时段）
			if (lstHoliday.size() > 0 && HolidayHelper.isHoliday(current, lstHoliday)) {
				continue;
			}
			// 获取周日历模板
			if (current.isBefore(workCalendar.getStartDate())) {
				workCalendar = WorkCalendarHelper.getWorkCalendar(lstWorkCalendar, current);
				week = weekHelper.getWeek(workCalendar.getWeekTemplateId());
			}
			Day day = week.getWeekDay(current.getDayOfWeek());
			workDay.setDay(day);
		}
		dc.setWorkDays(lstWorkDay);
		return dc;
	}

	public static DepartmentCalendarHelper testData() {
		DepartmentCalendarHelper helper = new DepartmentCalendarHelper(Department.testDatas(),
				DepartmentWorker.testDatas(), WeekTemplateDetail.testDatas(), WorkCalendar.testDatas(),
				Holiday.testDatas(), SpecialWorkDay.testDatas());
		helper.setRange(LocalDate.parse("2024-10-01"), LocalDate.parse("2025-10-01"));
		return helper;
	}

}
